﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq.Expressions;
using System.Linq;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel.DataAnnotations;
using System.ServiceModel.DomainServices.Client;
using System.Collections.ObjectModel;
using MVVMFramework.Core.Model;

namespace MVVMFramework.Core.Model
{
    public interface IDomainQuery : IDisposable
    {
        void Cancel();
        void Load();

        event Action Loading;
        event Action<ILoadOperation> Loaded;
        event Action Canceled;

        bool IsLoading { get; }
    }

    public interface IDomainQuery<T> : IDomainQuery
    {
        /// <summary>
        /// Delegate that returns a lambda expression to apply in a Where operation
        /// </summary>
        Func<Expression<Func<T, bool>>> FilterExpression { get; set; }

        /// <summary>
        /// SortDescription values that are applied in a OrderBy/ThenBy operation
        /// </summary>
        Func<SortDescriptionCollection> SortDescriptions { get; set; }

        /// <summary>
        /// Contains the required data that are applied in a Skip and Take operation
        /// </summary>
        Func<PageDescription> PageDescription { get; set; }

        new event Action<ILoadOperation<T>> Loaded;
    }

    public sealed class PageDescription
    {
        public int PageSize { get; set; }
        public int PageIndex { get; set; }
    }

    /// <summary>
    /// Not supported
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TProjection"></typeparam>
    public interface IDomainQuery<T, TProjection> : IDomainQuery<T>
    {
        Func<Expression<Func<T, TProjection>>> ProjectionExpression { get; set; }

        new event Action<ILoadOperation<TProjection>> Loaded;
    }



    
}
